package com.tianqi.modules.pms.service.impl;

import com.nlf.calendar.EightChar;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import com.tianqi.common.api.CommonResult;
import com.tianqi.common.enums.ShanXiangYuanLongEnum;
import com.tianqi.common.exception.ApiException;
import com.tianqi.common.utils.TimeUtils;
import com.tianqi.modules.pms.dto.request.ShuZiPaiPanReqDTO;
import com.tianqi.modules.pms.dto.request.XkFeiXingReqDTO;
import com.tianqi.modules.pms.dto.response.*;
import com.tianqi.modules.pms.service.XKFeiXingService;
import com.tianqi.modules.tqs.constant.LetterMapConstant;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @className: XKFeiXingServiceImpl
 * @description: 玄空飞星，数字排盘实现类
 * @author: zp
 * @create: 2023-08-24 19:18
 **/
@Service
@Slf4j
public class XKFeiXingServiceImpl implements XKFeiXingService {
    @Autowired
    private TimeUtils timeUtils;
    @Override
    public CommonResult<ShuZiPaiPanRespDTO> getShuZiPaiPan(ShuZiPaiPanReqDTO shuZiPaiPanReqDTO) {
        ShuZiPaiPanRespDTO resultData=new ShuZiPaiPanRespDTO();
        resultData.setNumber(shuZiPaiPanReqDTO.getNumber());
        final String[] number = {resultData.getNumber()};
        //将字母替换成数字
        Map<String,String> letterNumberMap= LetterMapConstant.LETTER_NUMBER_MAP;
        letterNumberMap.forEach((key, value)->{
            if(number[0].indexOf(key)!=-1){
                number[0]=number[0].replaceAll(key, value);
            }
        });
        resultData.setResultNumber(number[0]);
        char[] charArray = number[0].toCharArray();
        List<Character> collect = new String(charArray).chars()
                .mapToObj(c -> (char) c)
                .collect(Collectors.toList());
        List<String> numberData=new ArrayList<>();
        collect.forEach((e)->{
            numberData.add(e.toString());
        });
        Map<String, ShuZiPaiPanShenShaDTO> resultMap=new HashMap<>();

        int numS=0;
        if(numberData.get(0).equals("0")||numberData.get(0).equals("5")){
            int numTemp=numS;
            int startNum=0;
            int no=0;
            Boolean flagTemp=true;
            String zhi=numberData.get(0);
            while (flagTemp) {
                ShuZiPaiPanShenShaDTO zeroData=new ShuZiPaiPanShenShaDTO();
                if(!numberData.get(numTemp+1).equals("0")&&!numberData.get(numTemp+1).equals("5")){
                    if(no>=0){
                        zeroData.setName(zhi.equals("0")?"隐藏":"放大");
                        resultMap.put(startNum+","+(startNum+no),zeroData);
                    }
                    break;
                }
               if(!numberData.get(numTemp+1).equals(zhi)){
                   zeroData.setName(zhi.equals("0")?"隐藏":"放大");
                   resultMap.put(startNum+","+numTemp,zeroData);
                   zhi=numberData.get(numTemp+1);
                   startNum=numTemp+1;
                   no=0;
               }else{
                   no=no+1;
               }

                numTemp=numTemp+1;
            }
            numS=numTemp+1;
        }
        int numE=number[0].length()-1;
        if(numberData.get(numE).equals("0")||numberData.get(numE).equals("5")){
            int numTemp=numE;
            int startNum=numE;
            int no=0;
            Boolean flagTemp=true;
            String zhi=numberData.get(numTemp);
            while (flagTemp) {
                ShuZiPaiPanShenShaDTO zeroData=new ShuZiPaiPanShenShaDTO();
                if(!numberData.get(numTemp-1).equals("0")&&!numberData.get(numTemp-1).equals("5")){
                    if(no>=0){
                        zeroData.setName(zhi.equals("0")?"隐藏":"放大");
                        resultMap.put((startNum-no)+","+startNum,zeroData);
                    }
                    break;
                }
                if(!numberData.get(numTemp-1).equals(zhi)){
                    zeroData.setName(zhi.equals("0")?"隐藏":"放大");
                    resultMap.put(numTemp+","+startNum,zeroData);
                    zhi=numberData.get(numTemp-1);
                    startNum=numTemp-1;
                    no=0;
                }else{
                    no=no+1;
                }

                numTemp=numTemp-1;
            }
            numE=numTemp;
        }
        int startNum=numS;
        int ZFStart=0;
        int start=0;
        int no=0;
        String zhi="";
        boolean flag=true;
//        if(numS==1&&numE==2){
//            ShuZiPaiPanShenShaDTO data=new ShuZiPaiPanShenShaDTO();
//            data.setName(LetterMapConstant.BAZHAISHENSHA_MAP.get(numberData.get(1)+numberData.get(1)));
//            resultMap.put(1+","+1,data);
//        }
        while (flag) {
            if(startNum>(numE-1)){
                break;
            }
            ShuZiPaiPanShenShaDTO data=new ShuZiPaiPanShenShaDTO();
            if(!numberData.get(startNum+1).equals("0")&&!numberData.get(startNum+1).equals("5")&&!numberData.get(startNum).equals("0")&&!numberData.get(startNum).equals("5")){
                data.setName(LetterMapConstant.BAZHAISHENSHA_MAP.get(numberData.get(startNum)+numberData.get(startNum+1)));
                resultMap.put(startNum+","+(startNum+1),data);
                if(no>0){
                    data.setName(zhi.equals("0")?"隐藏":"放大");
                    resultMap.put(ZFStart+","+(startNum),data);
                    zhi="";
                    data.setName(LetterMapConstant.BAZHAISHENSHA_MAP.get(numberData.get(start)+numberData.get(startNum)));
                    resultMap.put(start+","+(startNum),data);
                    start=0;
                    no=0;
                }else if(no==0&&!zhi.equals("")){
                    zhi="";
                    data.setName(LetterMapConstant.BAZHAISHENSHA_MAP.get(numberData.get(start)+numberData.get(startNum)));
                    resultMap.put(start+","+(startNum),data);
                    start=0;
                    no=0;
                }
            }else{
                if(zhi.equals("")){
                    zhi=numberData.get(startNum+1);
                    ZFStart=startNum+1;
                    start=startNum;
                }else{
                    if(!numberData.get(startNum+1).equals(zhi)){
                        data.setName(zhi.equals("0")?"隐藏":"放大");
                        resultMap.put(ZFStart+","+startNum,data);
                        zhi=numberData.get(startNum+1);
                        ZFStart=startNum+1;
                        no=0;
                    }else{
                        no=no+1;
                    }
                }

            }
            startNum=startNum+1;
        }
        resultData.setShuZiShenSha(resultMap);
        List<String> xiaBiaoList=new ArrayList<>();
        resultData.getShuZiShenSha().forEach((k,v)->{
            xiaBiaoList.add(k);
        });
        resultData.setXiaBiaoList(xiaBiaoList);
        return CommonResult.success(resultData);
    }

    @Override
    public CommonResult<XkFeiXingRespDTO> getXKFeiXing(XkFeiXingReqDTO xkFeiXingReqDTO) {
        XkFeiXingRespDTO resultData=new XkFeiXingRespDTO();
        Map<String, XkFeiXingPan> xkFeiXingPan=new HashMap<>();
        XkFeiXingPan one=new XkFeiXingPan();
        xkFeiXingPan.put("one",one);

        XkFeiXingPan two=new XkFeiXingPan();
        xkFeiXingPan.put("two",two);

        XkFeiXingPan three=new XkFeiXingPan();
        xkFeiXingPan.put("three",three);

        XkFeiXingPan four=new XkFeiXingPan();
        xkFeiXingPan.put("four",four);

        XkFeiXingPan five=new XkFeiXingPan();
        xkFeiXingPan.put("five",five);

        XkFeiXingPan six=new XkFeiXingPan();
        xkFeiXingPan.put("six",six);

        XkFeiXingPan seven=new XkFeiXingPan();
        xkFeiXingPan.put("seven",seven);

        XkFeiXingPan eight=new XkFeiXingPan();
        xkFeiXingPan.put("eight",eight);

        XkFeiXingPan nine=new XkFeiXingPan();
        xkFeiXingPan.put("nine",nine);

        for(int i=1;i<10;i++){
            xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(String.valueOf(i))).setYunPanNo(LetterMapConstant.NUMBERDUIZHAO_MAP.get(LetterMapConstant.DAYUNFEIXING_MAP.get(xkFeiXingReqDTO.getSanYuanJiuYun()+"运_"+i)));
            xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(String.valueOf(i))).setFangXiang(LetterMapConstant.DAXIENUMBERFXDUIZHAO_MAP.get(LetterMapConstant.NUMBERDUIZHAO_MAP.get(String.valueOf(i))));
            xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(String.valueOf(i))).setShan("");
            xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(String.valueOf(i))).setXiang("");
        }
        //确定山向
        String shan=LetterMapConstant.SHANXIANGPAILIE_MAP.get(xkFeiXingReqDTO.getShanXiang()).split("_")[0];
        String xiang=LetterMapConstant.SHANXIANGPAILIE_MAP.get(xkFeiXingReqDTO.getShanXiang()).split("_")[1];
        ShanXiangYuanLongEnum shanEnum=ShanXiangYuanLongEnum.getValueByelShan(shan);
        String shanGong= shanEnum.getGong().substring(0,1);
        ShanXiangYuanLongEnum xiangEnum=ShanXiangYuanLongEnum.getValueByelShan(xiang);
        String xiangGong= xiangEnum.getGong().substring(0,1);
        xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(shanGong)).setShan(shan+"山");
        xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(xiangGong)).setXiang(xiang+"向");
        //确定中宫山向数字
        String shanNo=LetterMapConstant.NUMBERDUIZHAO_MAP.get(xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(shanGong)).getYunPanNo());
        String xiangNo=LetterMapConstant.NUMBERDUIZHAO_MAP.get(xkFeiXingPan.get(LetterMapConstant.NUMBERENDUIZHAO_MAP.get(xiangGong)).getYunPanNo());
        //确定山向阴阳  阳龙顺飞,阴龙逆飞
        String shanYinYang=ShanXiangYuanLongEnum.getYinyangByGong(shanNo+"宫",shanEnum.getYuanlong());
        String xiangYinYang=ShanXiangYuanLongEnum.getYinyangByGong(xiangNo+"宫",xiangEnum.getYuanlong());
        Integer shanNoFlag=Integer.valueOf(shanNo);
        Integer xiangNoFlag=Integer.valueOf(xiangNo);
        Date date=new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try{
            date = format.parse(xkFeiXingReqDTO.getDate());
            resultData.setDateStr(format.format(date));
            // 计算真太阳时
            if (xkFeiXingReqDTO.getTrueSolarTime() != null && xkFeiXingReqDTO.getTrueSolarTime()) {
                if (StringUtils.isEmpty(xkFeiXingReqDTO.getLocation())) {
                    throw new ApiException("计算真太阳时地点不能为空");
                }
                TimeConvertResultDTO timeConvertResultDTO = timeUtils.getTimeConvert(date,
                        xkFeiXingReqDTO.getLocation());
                date = timeConvertResultDTO.getDate();
                xkFeiXingReqDTO.setLatAndLon(timeConvertResultDTO.getLocation());
                xkFeiXingReqDTO.setDateStr(format.format(date));
                resultData.setDateStr(format.format(date));
            }

        }catch(ParseException e){
            e.printStackTrace();
            return CommonResult.failed(e.getMessage());
        }catch(Exception e){
            e.printStackTrace();
            return CommonResult.failed(e.getMessage());
        }

        //日期实例化
        Solar solar = Solar.fromDate(date);
        //时间转阴历
        Lunar lunar = solar.getLunar();
        Date liChuanTime= new Date();
        try {
            //获取立春交接时刻时间
            String liChunJiaoJieTime=lunar.getJieQiTable().get("立春").toYmdHms();
            liChuanTime=format.parse(liChunJiaoJieTime);
        }catch(ParseException e){
            e.printStackTrace();
            return CommonResult.failed(e.getMessage());
        }catch(Exception e){
            e.printStackTrace();
            return CommonResult.failed(e.getMessage());
        }
        //计算当前年
        String yearNow=(date.getTime()-liChuanTime.getTime())>0?String.valueOf(lunar.getYear()):String.valueOf(lunar.getYear()-1);
        //获取八字
        EightChar eightCharQuery=lunar.getEightChar();
        // 设置流派1
        eightCharQuery.setSect(1);
        resultData.setQuestion(xkFeiXingReqDTO.getQuestion());
        resultData.setYearInGanZhi(eightCharQuery.getYear());
        resultData.setYearInXunKong(eightCharQuery.getYearXunKong());
        resultData.setMonthInGanZhi(eightCharQuery.getMonth());
        resultData.setMonthInXunKong(eightCharQuery.getMonthXunKong());
        resultData.setDayInGanZhi(eightCharQuery.getDay());
        resultData.setDayInXunKong(eightCharQuery.getDayXunKong());
        resultData.setTimeInGanZhi(eightCharQuery.getTime());
        resultData.setTimeInXunKong(eightCharQuery.getTimeXunKong());

        Integer yearNoFlag=Integer.valueOf(LetterMapConstant.LIUNIANFEIXING_MAP.get(yearNow));
        Integer monthNoFlag=Integer.valueOf(LetterMapConstant.LIUYUEFEIXING_MAP.get(eightCharQuery.getMonthZhi()+eightCharQuery.getYearZhi()));
        String dayData=LetterMapConstant.LIURIFEIXING_MAP.get(String.valueOf(lunar.getPrevJieQi(false))+"_"+eightCharQuery.getDay());
        Integer dayNoFlag=Integer.valueOf(dayData.split("_")[0]);
        String dayShunNi=dayData.split("_")[1];
        String timeShunNi=LetterMapConstant.LIUSHIFEIXING_JIEQISHUNNI_MAP.get(String.valueOf(lunar.getPrevJieQi(false)));
        Integer timeNoFlag=Integer.valueOf(timeShunNi.equals("顺")?LetterMapConstant.LIUSHIFEIXING_DONGZHI_MAP.get(eightCharQuery.getTimeZhi()+eightCharQuery.getDayZhi()):LetterMapConstant.LIUSHIFEIXING_XIAZHI_MAP.get(eightCharQuery.getTimeZhi()+eightCharQuery.getDayZhi()));


        //中宫赋值
        xkFeiXingPan.get("five").setShanNo(shanNo);
        xkFeiXingPan.get("five").setXiangNo(xiangNo);
        xkFeiXingPan.get("five").setYear(String.valueOf(yearNoFlag));
        xkFeiXingPan.get("five").setMonth(String.valueOf(monthNoFlag));
        xkFeiXingPan.get("five").setDay(String.valueOf(dayNoFlag));
        xkFeiXingPan.get("five").setHour(String.valueOf(timeNoFlag));
        //飞星顺序
        String[] feiXingShunXu={"six","seven","eight","nine","one","two","three","four"};
        for(int j=0;j<feiXingShunXu.length;j++){
            //山赋值
            if(shanYinYang.equals("阳")){
                if((shanNoFlag+1)==10){
                    shanNoFlag=0;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setShanNo(String.valueOf(shanNoFlag+1));
                shanNoFlag=shanNoFlag+1;
            }else{
                if((shanNoFlag-1)==0){
                    shanNoFlag=10;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setShanNo(String.valueOf(shanNoFlag-1));
                shanNoFlag=shanNoFlag-1;

            }
            //向赋值
            if(xiangYinYang.equals("阳")){
                if((xiangNoFlag+1)==10){
                    xiangNoFlag=0;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setXiangNo(String.valueOf(xiangNoFlag+1));
                xiangNoFlag=xiangNoFlag+1;
            }else{
                if((xiangNoFlag-1)==0){
                    xiangNoFlag=10;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setXiangNo(String.valueOf(xiangNoFlag-1));
                xiangNoFlag=xiangNoFlag-1;
            }
            //年赋值
            if((yearNoFlag+1)==10){
                yearNoFlag=0;
            }
            xkFeiXingPan.get(feiXingShunXu[j]).setYear(String.valueOf(yearNoFlag+1));
            yearNoFlag=yearNoFlag+1;
            //月赋值
            if((monthNoFlag+1)==10){
                monthNoFlag=0;
            }
            xkFeiXingPan.get(feiXingShunXu[j]).setMonth(String.valueOf(monthNoFlag+1));
            monthNoFlag=monthNoFlag+1;
            //日赋值
            if(dayShunNi.equals("顺") || xkFeiXingReqDTO.getDayFeiType()==2){
                if((dayNoFlag+1)==10){
                    dayNoFlag=0;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setDay(String.valueOf(dayNoFlag+1));
                dayNoFlag=dayNoFlag+1;
            }else{
                if((dayNoFlag-1)==0){
                    dayNoFlag=10;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setDay(String.valueOf(dayNoFlag-1));
                dayNoFlag=dayNoFlag-1;
            }
            //时赋值
            if(timeShunNi.equals("顺")){
                if((timeNoFlag+1)==10){
                    timeNoFlag=0;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setHour(String.valueOf(timeNoFlag+1));
                timeNoFlag=timeNoFlag+1;
            }else{
                if((timeNoFlag-1)==0){
                    timeNoFlag=10;
                }
                xkFeiXingPan.get(feiXingShunXu[j]).setHour(String.valueOf(timeNoFlag-1));
                timeNoFlag=timeNoFlag-1;
            }
        }

        resultData.setXkFeiXingPan(xkFeiXingPan);
        return CommonResult.success(resultData);
    }

    public static List<String> splitToList(String str, String separator) {
        if (str == null || str.isEmpty()) {
            return Collections.emptyList();
        }
        if (separator == null || separator.isEmpty()) {
            return Collections.singletonList(str);
        }
        return Arrays.asList(str.split(separator));
    }
}
